package com.lx.ngsl.exam.quest.service;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.Optional;

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Expression;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.lx.ngsl.exam.quest.entity.ChoiceEntity;
import com.lx.ngsl.exam.quest.entity.QuestEntity;
import com.lx.ngsl.exam.quest.entity.TagEntity;
import com.lx.ngsl.exam.quest.repository.ChoiceRepository;
import com.lx.ngsl.exam.quest.repository.QuestRepository;
import com.lx.ngsl.exam.quest.repository.TagRepository;
import com.lx.ngsl.util.UuidUtil;

@Service
public class QuestService {
	@Value("${app.file-path}")
	protected String uploadLocation;

	@Autowired
	private QuestRepository repository;
	@Autowired
	private TagRepository tagRepository;
	@Autowired
	private ChoiceRepository choiceRepository;
	
	/**
	 * 
	 * <p>Method ：questListPage
	 * <p>Description : 试题分页多条件查询
	 *
	 * @param type 题型
	 * @param tag 标签
	 * @param quest 题目
	 * @param pageable 分页对象
	 * @return
	 * @throws Exception 
	 *</p>
	 */
	public Page<QuestEntity> questListPage(String type,String tag,String quest, Pageable pageable){
		
		Page<QuestEntity> list = repository.findAll(new Specification<QuestEntity>() {
			@Override
			public Predicate toPredicate(Root<QuestEntity> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate predicate = cb.conjunction();
				List<Expression<Boolean>> expressions = predicate.getExpressions();
				expressions.add(cb.equal(root.<String> get("status"), "1"));
				if (!StringUtils.isEmpty(type)) {
					expressions.add(cb.equal(root.<String> get("type"), type));
				}
				if (!StringUtils.isEmpty(tag)) {
					expressions.add(cb.equal(root.<String> get("tag"), tag));
				}
				if (!StringUtils.isEmpty(quest)) {
					expressions.add(cb.like(root.<String> get("quest"), "%" + quest + "%"));
				}
				return predicate;
			}
		}, pageable);

		return list;
	}
	
	/*
	 * 保存试题
	 */
	public boolean saveQuest(QuestEntity quest) {
		List<QuestEntity> quests = repository.findByQuest(quest.getQuest());
		if(quests != null && quests.size() > 0) {
			return false;
		}
		quest.setId(UuidUtil.id());
		repository.save(quest);
		return true;
	}
	
	/**
	 * 
	 * <p>Method ：saveImg
	 * <p>Description : 保存图片
	 *
	 * @param file
	 * @param name
	 * @return 
	 *</p>
	 */
	public String saveImg(MultipartFile file,String name) {
		String filepath = "";
		if (!file.isEmpty()) {
			try {
				byte[] bytes = file.getBytes();
				//文件名称为name拼接当前时间字符串
				DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); 
		        String filename = name+df.format(new Date())+"."+file.getOriginalFilename().substring(file.getOriginalFilename().lastIndexOf(".")+1); 
				File nfile = new File(uploadLocation+"/quest");
				if (!nfile.exists()) { // 如果路径不存在，创建
					nfile.mkdirs();
				}	
				//写入文件
				BufferedOutputStream stream = new BufferedOutputStream(
						new FileOutputStream(new File(nfile.getPath() + File.separator + filename)));
				stream.write(bytes);
				stream.close();
				//数据库存储路径
				filepath = nfile.getPath() + File.separator + filename;	
				
			} catch (IOException e) {
				e.printStackTrace();
				return null;
			}
		}
		
		return filepath;
		
	}
	/*
	 * 新增试题
	 */
	@Transactional
	public void addQuest(String tag,String quest,String type,String choices, MultipartFile img) {
		List<ChoiceEntity> options = JSON.parseObject(choices, new TypeReference<List<ChoiceEntity>>() {});
		//存储试题
		QuestEntity q = new QuestEntity();
		String id = UuidUtil.id();
		q.setId(id);
		q.setStatus("1");
		if(img != null) {
			String imgPth = saveImg(img, "QUEST_IMG_");
			q.setImg(imgPth);
		}
		q.setQuest(quest);
		q.setTag(tag);
		q.setType(type);
		saveQuest(q);
		//存储选项
		for(ChoiceEntity c : options) {
			c.setId(UuidUtil.id());
			c.setQuestId(id);
		}
		choiceRepository.saveAll(options);
	}
	
	/*
	 * 新增试题
	 */
	@Transactional
	public void addQuest(String tag,String quest,String type,String answer) {
		//存储试题
		QuestEntity q = new QuestEntity();
		String id = UuidUtil.id();
		q.setId(id);
		q.setStatus("1");
		q.setQuest(quest);
		q.setTag(tag);
		q.setType(type);
		saveQuest(q);
		//存储选项
		ChoiceEntity c = new ChoiceEntity();
		c.setId(UuidUtil.id());
		c.setIsTrue("1");
		c.setQuestId(id);
		c.setContent(answer);
		choiceRepository.save(c);
	}
	/*
	 * 查询标签
	 */
	public List<TagEntity> queryTags(){
		return tagRepository.findAll(new Sort(Direction.ASC,"id"));
	}
	/*
	 * 删除(逻辑删除)
	 */
	@Transactional
	public boolean del(String questId) {
		//删除试题
		Optional<QuestEntity> quest = repository.findById(questId);
		if(!quest.isPresent()) {
			return false;
		}
		QuestEntity entity = quest.get();
		if("0".equals(entity.getStatus())){
			return true;
		}
		entity.setStatus("0");
		repository.save(entity);
		//删除试题的选项
		choiceRepository.deleteByQuestId(questId);
		return true;
	}
	
	/*
	 * 试题查询
	 */
	public List<QuestEntity> findByIds(List<String> ids){
		return repository.findByIds(ids);
	}
	/*
	 * 查询试题选项
	 */
	public List<ChoiceEntity> getChoices(String questId){
		return choiceRepository.findByQuestId(questId);
	}
	
	/*
	 * 查询试题的答案
	 */
	public String getAnswer(String questId,String type) {
		if("判断题".equals(type)) {
			List<ChoiceEntity> choices = choiceRepository.getChoices(questId);
			if(choices == null || choices.size() == 0) {
				return "";
			}
			return choices.get(0).getIsTrue();
		}
		List<String> inxs = choiceRepository.getCorrectChoice(questId);
		if(inxs == null || inxs.size() == 0) {
			return "";
		}else {
			return String.join("", inxs);
		}
	}

}
